package com.xueyi.starter.utils;

import lombok.AllArgsConstructor;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolAbstract;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.params.ZAddParams;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author LuQi
 * @类描述 JedisUtil
 * @时间 2021/6/24
 */
@Component
@AllArgsConstructor
public class JedisUtil {


    private final JedisPoolAbstract jedisPoolAbstract;
    private final RedissonClient redissonClient;

    /**
     * 获取排行榜中指定的排行信息（ 从低到高 ）
     *
     * @param rankingKey 排行榜的key
     * @param start      从哪里开始（索引0）
     * @param end        从哪里结束
     * @param jedis
     * @return
     */
    public Set<String> findRankingAsc(String rankingKey, Integer start, Integer end,
                                      Jedis jedis) {

        if (jedis != null) {
            return jedis.zrevrange(rankingKey, start, end);
        } else {
            Jedis resource = null;
            try {
                resource = jedisPoolAbstract.getResource();
                return resource.zrevrange(rankingKey, start, end);
            } finally {
                FinalUtil.unLockAndCloseRedis(resource);
            }
        }
    }

    /**
     * 获取排行榜中指定的排行信息（ 从高到低 ）
     *
     * @param rankingKey 排行榜的key
     * @param start      从哪里开始（索引0）
     * @param end        从哪里结束
     * @param jedis
     * @return
     */
    public Set<String> findRankingDesc(String rankingKey, Integer start, Integer end,
                                       Jedis jedis) {

        if (jedis != null) {
            return jedis.zrange(rankingKey, start, end);
        } else {
            Jedis resource = null;
            try {
                resource = jedisPoolAbstract.getResource();
                return resource.zrange(rankingKey, start, end);
            } finally {
                FinalUtil.unLockAndCloseRedis(resource);
            }
        }
    }

    /**
     * 往排行榜中添加一个名次（ 如果该名称在排行榜中已经存在的话则是对score进行加分)
     * 排行榜的排序参数是根据score去约束的
     *
     * @param rankingKey 排行榜的key（必填)
     * @param itemKey    参与排行榜中的key（ 比如用户的id)（必填)
     * @param score      本次新增的积分（必填)
     * @param jedis      jedis实例
     */
    public Double addRanking(String rankingKey, String itemKey, Integer score, Jedis jedis) {

        if (jedis != null) {
            return jedis.zaddIncr(rankingKey, score, itemKey, ZAddParams.zAddParams());
        } else {
            Jedis resource = null;
            try {
                resource = jedisPoolAbstract.getResource();
                return resource.zaddIncr(rankingKey, score, itemKey, ZAddParams.zAddParams());
            } finally {
                FinalUtil.unLockAndCloseRedis(resource);
            }
        }
    }

    /**
     * 一次性取出多个值
     *
     * @param key
     * @param size
     * @return
     */
    public List<String> multiPopPipeline(String key, int size) {

        List<String> sizeArr = new ArrayList<>();
        List<Response<String>> respArr = new ArrayList<>();
        Jedis resource = jedisPoolAbstract.getResource();
        try {
            Pipeline pipelined = resource.pipelined();
            for (int i = 0; i < size; i++) {
                Response<String> response = pipelined.lpop(key);
                respArr.add(response);
            }
            pipelined.sync();
            for (Response<String> stringResponse : respArr) {
                String onePop = stringResponse.get();
                if (!StringUtils.hasLength(onePop)) {
                    break;
                }
                sizeArr.add(onePop);
            }
            return sizeArr;
        } finally {
            FinalUtil.unLockAndCloseRedis(resource);
        }
    }

    public Jedis getJedis() {
        return jedisPoolAbstract.getResource();
    }
}
